為狀態機各個狀態加上名稱吧


Posted by tienyao on 2021-08-09

在模擬時為狀態機加上名稱,可以清楚瞭解目前狀態就不用看著單調的數字了,因為ASCII一個字元需要8 bit,所以在定義儲存空間時需要把可能最大的字元數乘8,此例是假設最大字元數為10 (reg [8*10-1:0] StateName),再為每個狀態取名子,模擬時就能清楚知道目前狀態機的狀態。

////// … . .. –.. .   – …. .   — — — . -. – //////                                                                                                                                                                                                              
// Author              : TienYao                                                                            
// Source Code Name    : StateMachineName.v                                                                                                 
// Function Description: For displaying state name in simulation                                                         
// ===========================================================
module StateMachineName
(
    input CLK,
    input nRST,
    output [7:0] STATE_OUT
);

reg  [3:0] current_state;
reg  [3:0] next_state;

reg  [7:0] rvCNT_q;
reg  [7:0] rvCNT_d;

reg  [7:0] rvData_TMP_q;
reg  [7:0] rvData_TMP_d;

localparam  S0_IDLE   = 4'd0,
            S1_STATE0 = 4'd1,
            S2_STATE1 = 4'd2,
            S3_STATE2 = 4'd3,
            S4_STATE3 = 4'd4,
            S5_FINISH = 4'd5;

always @(posedge CLK or negedge nRST)
begin
    if(!nRST)
        current_state <= S0_IDLE;
    else
        current_state <= next_state;
end

always @(*)
begin
    case(current_state)
    S0_IDLE:
    begin
        if(rvCNT_q == 8'd99)
            next_state = S1_STATE0;
        else
            next_state = current_state;
    end
    S1_STATE0:
    begin
        if(rvCNT_q == 8'd99)
            next_state = S2_STATE1;
        else
            next_state = current_state;
    end
    S2_STATE1:
    begin
        if(rvCNT_q == 8'd99)
            next_state = S3_STATE2;
        else
            next_state = current_state;
    end
    S3_STATE2:
    begin
        if(rvCNT_q == 8'd99)
            next_state = S4_STATE3;
        else
            next_state = current_state;
    end
    S4_STATE3:
    begin
        if(rvCNT_q == 8'd99)
            next_state = S5_FINISH;
        else
            next_state = current_state;
    end
    S5_FINISH:
    begin
        if(rvCNT_q == 8'd99)
            next_state = S0_IDLE;
        else
            next_state = current_state;
    end
    default:
    begin
        next_state = S0_IDLE;
    end
    endcase
end

always @(posedge CLK or negedge nRST)
begin
    if(!nRST)
        rvData_TMP_q <= 8'b0000_0000;
    else
        rvData_TMP_q <= rvData_TMP_d;
end

always @(*)
begin
    case(current_state)
        S0_IDLE  : rvData_TMP_d = 8'b0000_0000;
        S1_STATE0: rvData_TMP_d = 8'b0000_0011;
        S2_STATE1: rvData_TMP_d = 8'b0000_1100;
        S3_STATE2: rvData_TMP_d = 8'b0011_0000;
        S4_STATE3: rvData_TMP_d = 8'b1100_0000;
        S5_FINISH: rvData_TMP_d = 8'b1111_1111;
        default:   rvData_TMP_d = 8'b0000_0000;
    endcase
end

assign STATE_OUT = rvData_TMP_q;

always @(posedge CLK or negedge nRST)
begin
    if(!nRST)
        rvCNT_q <= 8'h0;
    else
        rvCNT_q <= rvCNT_d;
end
always @(*)
begin
    if(current_state != next_state)
        rvCNT_d = 8'h0;
    else if(rvCNT_q < 8'd99)
        rvCNT_d = rvCNT_q + 8'd1;
    else
        rvCNT_d = 8'h0;
end


reg [8*10–1:0] StateName;
always @(*)
begin
    case(current_state)
        S0_IDLE  : StateName = "IDLE";
        S1_STATE0: StateName = "STATE0";
        S2_STATE1: StateName = "STATE1";
        S3_STATE2: StateName = "STATE2";
        S4_STATE3: StateName = "STATE3";
        S5_FINISH: StateName = "FINISH";
        default  : StateName = "ERROR";
    endcase
end

endmodule

#verilog







Related Posts

Git 版本控制(下)

Git 版本控制(下)

Ajax Type Ahead

Ajax Type Ahead

閉包 Closure

閉包 Closure


Comments